home *** CD-ROM | disk | FTP | other *** search
- #include "bbs.h"
-
- #include "zmodem.h"
-
- #define SLEEP_LOGOFF 2
-
- short update_crc16(int cp, short crc);
- long update_crc32(int cp, long crc);
-
- extern BPTR fh;
- extern char *SkipdFiles;
- extern long zbaud, zbufsize, TMPBT;
- extern int sendlen, doublebuffer, zresume, NumSkipd;
- extern char *sendbuff, *zdiskbuff, *zbuffer, sbuff[];
- extern ULONG STpos;
-
- int tryzhdrtype; /* Header type to send corresponding to Last rx close */
- int Zctlesc,start; /* Don't escape control characters */
- int transfering=0;
- char txbuf[1024];
-
- long chinseg;
- char ZPathname[257];
- long filesize;
- long resumesize;
- int Rxbuflen;
- int Rxflags;
-
- int Rxframeind; /* ZBIN ZBIN32, or ZHEX type of frame received */
- int Rxtype; /* Type of header received */
- int Rxcount; /* Count of data bytes received */
- char Rxhdr[4]; /* Received header */
- char Txhdr[4]; /* Transmitted header */
- long Rxpos; /* Received file position */
- long Txpos; /* Transmitted file position */
- int Txfcs32; /* TRUE means send binary frames with 32 bit FCS */
- int Crc32t; /* Display flag indicating 32 bit CRC being sent */
- int Crc32; /* Display flag indicating 32 bit CRC being received */
- char Attn[ZATTNLEN+1]; /* Attention string rx sends to tx on err */
- int lastsent; /* Last char we sent */
- int zsrCDstat;
-
- FILE *f;
-
- //(RTS)
- /*
- * ZMODEM protocol primitives
- * Chuck Forsberg Omen Technology Inc.
- *
- * Entry point Functions:
- * zsbhdr(type, hdr) send binary header
- * zshhdr(type, hdr) send hex header
- * zgethdr(hdr, eflag) receive header - binary or hex
- * zsdata(buf, len, frameend) send data
- * zrdata(buf, len) receive data
- * stohdr(pos) store position data in Txhdr
- * long rclhdr(hdr) recover position offset from header
- */
-
- static long rclhdr(char *hdr);
- static void zputhex(int c), zmputs(char *s);
- static void zsda32(char *buf, int length, int frameend);
- static void zsdata(char *buf, int length, int frameend);
- static void zshhdr(int type, char *hdr);
- static void zsbh32(int type, char *hdr);
- static void zsbhdr(int type, char *hdr);
- static void stohdr(long pos), ackbibi(void), canit(void), putsec(void);
-
- static int noxrd7(void), zdlread(void), zgethex(void), zrhhdr(char *hdr);
- static int zrbhdr(char *hdr), zrbhdr32(char *hdr), zgethdr(char *hdr);
- static int zrdat32(char *buf, int length), zrdata(char *buf, int length);
- static int procheader(char *name), zsendfile(char *buf, int blen);
- static int zsendfdata(void), getinsync(void), saybibi(void);
- static int rzfile(void), rzfiles(void), tryz(void);
- static int getzrxinit(void);
-
- /*
- * Read a character from the modem line with timeout.
- * Eat parity, XON and XOFF characters.
- */
-
-
- static void ZErrDisplay(char *s)
- {
- char temp[50];
-
- ZmodemStatPrint("12H");
- ZmodemStatPrint(" ");
- ZmodemStatPrint("12H");
- ZmodemStatPrint(s);
- ZmodemStatPrint("12H");
- strcpy(ZModemInfo.ZStat,s);
- ZModemInfo.ErrorPos=ZModemInfo.RecPos;
- sprintf(temp,"%ld ",ZModemInfo.ErrorPos);
- ZmodemStatPrint(temp);
- }
-
-
- static void ZPrintClear(char *s)
- {
- ZmodemStatPrint(s);
- ZmodemStatPrint(" ");
- }
-
-
- static int noxrd7(void)
- {
- register int c;
-
- for (;;) {
- if ((c = readbyte()) < 0) return c;
- switch (c &= 0x7F) {
- case XON:
- case XOFF:
- continue;
- default:
- if (Zctlesc && !(c & 0x60)) continue;
- case '\r': case '\n': case ZDLE:
- return c;
- }
- }
- }
-
- /*
- * Read a byte, checking for ZMODEM escape encoding
- * including CAN*5 which represents a quick abort
- */
- static int zdlread(void)
- {
- register int c;
-
- again:
- /* Quick check for non control characters */
- if ((c = readbyte()) & 0x60) return c;
- switch (c) {
- case ZDLE: break;
- case 0x13: case 0x93: case 0x11: case 0x91:
- goto again;
- default:
- if (Zctlesc && !(c & 0x60)) goto again;
- return c;
- }
- again2:
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE) return CAN;
- if ((c = readbyte()) < 0) return c;
-
- if (c == CAN && (c = readbyte()) < 0) return c;
- if (c == CAN && (c = readbyte()) < 0) return c;
- if (c == CAN && (c = readbyte()) < 0) return c;
- switch (c) {
- case CAN: return GOTCAN;
- case ZCRCE: case ZCRCG: case ZCRCQ: case ZCRCW:
- return (c | GOTOR);
- case ZRUB0: return 0x7F;
- case ZRUB1: return 0xFF;
- case 0x13: case 0x93: case 0x11: case 0x91:
- goto again2;
- default:
- if (Zctlesc && ! (c & 0x60)) goto again2;
- if ((c & 0x60) == 0x40) return(c ^ 0x40);
- break;
- }
- sprintf(sbuff, "Bad escape sequence %x", c);
- ZErrDisplay(sbuff);
- return ERROR;
- }
-
- /* Decode two lower case hex digits into an 8 bit byte value */
- static int zgethex(void)
- {
- register int c, n;
-
- if ((c = noxrd7()) < 0) return c;
- n = c - '0';
- if (n > 9) n -= ('a' - ':');
- if (n & ~0xF) return ERROR;
- if ((c = noxrd7()) < 0) return c;
-
- c -= '0';
- if (c > 9) c -= ('a' - ':');
- if (c & ~0xF) return ERROR;
- c += (n<<4);
- return c;
- }
-
- /* Receive a hex style header (type and position) */
- static int zrhhdr(char *hdr)
- {
- register int c;
- register unsigned short crc;
- register int n;
-
- if ((c = zgethex()) < 0) return c;
- Rxtype = c;
- crc = update_crc16(c, 0);
-
- for (n=4; --n >= 0; ++hdr) {
- if ((c = zgethex()) < 0)
- return c;
- crc = update_crc16(c, crc);
- *hdr = c;
- }
- if ((c = zgethex()) < 0)
- return c;
- crc = update_crc16(c, crc);
- if ((c = zgethex()) < 0)
- return c;
- crc = update_crc16(c, crc);
- if (crc & 0xFFFF)
- {
- ZErrDisplay("Bad CRC"); return ERROR;
- }
- switch ( c = readbyte())
- {
- case 0x8D:
- case 0xD:
- /* Throw away possible cr/lf */
- readbyte();
- }
- return Rxtype;
- }
-
- /* Receive a binary style header (type and position) */
- static int zrbhdr(char *hdr)
- {
- register int c, n;
- register unsigned short crc;
-
- if ((c = zdlread()) & ~0xFF)
- return c;
- Rxtype = c;
- crc = update_crc16(c, 0);
-
- for (n=4; --n >= 0; ++hdr)
- {
- if ((c = zdlread()) & ~0xFF)
- return c;
- crc = update_crc16(c, crc);
- *hdr = c;
- }
- if ((c = zdlread()) & ~0xFF)
- return c;
- crc = update_crc16(c, crc);
- if ((c = zdlread()) & ~0xFF)
- return c;
- crc = update_crc16(c, crc);
- if (crc & 0xFFFF)
- {
- ZErrDisplay("Bad CRC");
- return ERROR;
- }
- return Rxtype;
- }
-
- /* Receive a binary style header (type and position) with 32 bit FCS */
- static int zrbhdr32(char *hdr)
- {
- register int c, n;
- register unsigned long crc;
-
- if ((c = zdlread()) & ~0xFF)
- return c;
- Rxtype = c;
- crc = 0xFFFFFFFFL; crc = update_crc32(c, crc);
-
- for (n=4; --n >= 0; ++hdr)
- {
- if ((c = zdlread()) & ~0xFF)
- return c;
- crc = update_crc32(c, crc);
- *hdr = c;
- }
- for (n=4; --n >= 0;)
- {
- if ((c = zdlread()) & ~0xFF)
- return c;
- crc = update_crc32(c, crc);
- }
-
- if (crc != 0xDEBB20E3L)
- {
- ZErrDisplay("Bad CRC");
- return ERROR;
- }
- return Rxtype;
- }
-
- /*
- * Read a ZMODEM header to hdr, either binary or hex.
- * eflag controls local display of non zmodem characters:
- * 0: no display
- * 1: display printing characters only
- * 2: display all non ZMODEM characters
- * set Rxpos and return type of header.
- * Otherwise return negative on error.
- * Return ERROR instantly if ZCRCW sequence, for fast error recovery.
- */
- static int zgethdr(char *hdr)
- {
- register int c, n, cancount;
-
- n = 1400 + zbaud; /* Max bytes before start of frame */
- Rxframeind = Rxtype = 0;
-
- startover:
- cancount = 5;
- again:
- /* Return immediate ERROR if ZCRCW sequence seen */
- switch (c = readbyte())
- {
- case RCDO:
- case TIMEOUT: {
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE)
- return NOCARRERROR;
- goto fifi;
- }
- case CAN:
- gotcan:
- if (--cancount <= 0) {
- c = ZCAN;
- goto fifi;
- }
- switch (c = readbyte()) {
- case TIMEOUT:
- goto again;
- case ZCRCW:
- c = ERROR;
- /* **** FALL THRU TO **** */
- case RCDO:
- goto fifi;
- default:
- break;
- case CAN:
- if (--cancount <= 0)
- {
- c = ZCAN; goto fifi;
- }
- goto again;
- }
- /* **** FALL THRU TO **** */
- default:
- agn2:
- if ( --n == 0)
- {
- ZErrDisplay("Garbage count exceeded");
- return(ERROR);
- }
- goto startover;
- case ZPAD|0x80: /* This is what we want. */
- case ZPAD: /* This is what we want. */
- break;
- }
- cancount = 5;
- splat:
- switch (c = noxrd7())
- {
- case ZPAD:
- goto splat;
- case RCDO:
- case TIMEOUT:
- goto fifi;
- default:
- goto agn2;
- case ZDLE: /* This is what we want. */
- break;
- }
-
- switch (c = noxrd7())
- {
- case RCDO:
- case TIMEOUT:
- goto fifi;
- case ZBIN:
- Rxframeind = ZBIN; Crc32 = FALSE;
- c = zrbhdr(hdr);
- break;
- case ZBIN32:
- Crc32 = Rxframeind = ZBIN32;
- c = zrbhdr32(hdr);
- break;
- case ZHEX:
- Rxframeind = ZHEX; Crc32 = FALSE;
- c = zrhhdr(hdr);
- break;
- case CAN:
- goto gotcan;
- default:
- goto agn2;
- }
- Rxpos = hdr[ZP3] & 0xFF;
- Rxpos = (Rxpos<<8) + (hdr[ZP2] & 0xFF);
- Rxpos = (Rxpos<<8) + (hdr[ZP1] & 0xFF);
- Rxpos = (Rxpos<<8) + (hdr[ZP0] & 0xFF);
- fifi:
- switch (c)
- {
- case GOTCAN:
- c = ZCAN;
- /* **** FALL THRU TO **** */
- case ZNAK:
- case ZCAN:
- case ERROR:
- case TIMEOUT:
- case RCDO:
- /* **** FALL THRU TO **** */
- default:
- break;
- }
- return c;
- }
-
- static int zrdat32(char *buf, int length)
- {
- register int c, d;
- register unsigned long crc;
- register char *end;
-
- crc = 0xFFFFFFFFL; Rxcount = 0; end = buf + length;
- while (buf <= end)
- {
- if ((c = zdlread()) & ~0xFF)
- {
- crcfoo:
- switch (c)
- {
- case GOTCRCE:
- case GOTCRCG:
- case GOTCRCQ:
- case GOTCRCW:
- crc = update_crc32(d=c, crc);
- if ((c = zdlread()) & ~0xFF)
- goto crcfoo;
- crc = update_crc32(c, crc);
- if ((c = zdlread()) & ~0xFF)
- goto crcfoo;
- crc = update_crc32(c, crc);
- if ((c = zdlread()) & ~0xFF)
- goto crcfoo;
- crc = update_crc32(c, crc);
- if ((c = zdlread()) & ~0xFF)
- goto crcfoo;
- crc = update_crc32(c, crc);
- if (crc != 0xDEBB20E3L)
- {
- ZErrDisplay("Bad CRC");
- return ERROR;
- }
- Rxcount = length - (end - buf);
- return d;
- case GOTCAN:
- ZErrDisplay("Sender Canceled");
- return ZCAN;
- case TIMEOUT:
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE) {
- return ERROR;
- }
- ZErrDisplay("TIMEOUT");
- return c;
- default:
- ZErrDisplay("Bad data subpacket");
- return c;
- }
- }
- *buf++ = c;
- crc = update_crc32(c, crc);
- }
- ZErrDisplay("Data subpacket too long");
- return ERROR;
- }
-
- /*
- * Receive array buf of max length with ending ZDLE sequence
- * and CRC. Returns the ending character or error code.
- * NB: On errors may store length+1 bytes!
- */
- static int zrdata(char *buf, int length)
- {
- register int c, d;
- register unsigned short crc;
- register char *end;
-
- if (Rxframeind == ZBIN32)
- return zrdat32(buf, length);
-
- crc = Rxcount = 0; end = buf + length;
- while (buf <= end)
- {
- if ((c = zdlread()) & ~0xFF)
- {
- crcfoo:
- switch (c)
- {
- case GOTCRCE:
- case GOTCRCG:
- case GOTCRCQ:
- case GOTCRCW:
- crc = update_crc16(d=c, crc);
- if ((c = zdlread()) & ~0xFF)
- goto crcfoo;
- crc = update_crc16(c, crc);
- if ((c = zdlread()) & ~0xFF)
- goto crcfoo;
- crc = update_crc16(c, crc);
- if (crc & 0xFFFF)
- {
- ZErrDisplay("Bad CRC");
- return ERROR;
- }
- Rxcount = length - (end - buf);
- return d;
- case GOTCAN:
- ZErrDisplay("Sender Canceled");
- return ZCAN;
- case TIMEOUT:
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE) {
- return ERROR;
- }
- ZErrDisplay("TIMEOUT");
- return c;
- default:
- ZErrDisplay("Bad data subpacket");
- return c;
- }
- }
- *buf++ = c;
- crc = update_crc16(c, crc);
- }
- ZErrDisplay("Data subpacket too long");
- return ERROR;
- }
-
-
- /* Recover a long integer from a header */
- static long rclhdr(char *hdr)
- {
- register long l;
-
- l = (hdr[ZP3] & 0xFF);
- l = (l << 8) | (hdr[ZP2] & 0xFF);
- l = (l << 8) | (hdr[ZP1] & 0xFF);
- l = (l << 8) | (hdr[ZP0] & 0xFF);
- return l;
- }
-
- /*
- * Send character c with ZMODEM escape sequence encoding.
- * Escape XON, XOFF. Escape CR following @ (Telenet net escape)
- */
- void zsendbyte(int c)
- {
- /* Quick check for non control characters */
- if (c & 0x60)
- sendbyte(lastsent = c);
- else
- {
- switch (c &= 0xFF)
- {
- case ZDLE:
- sendbyte(ZDLE);
- sendbyte(lastsent = (c ^= 0x40));
- break;
- case 0xD:
- case 0x8D:
- if (!Zctlesc && (lastsent & 0x7F) != '@')
- goto sendit;
- /* **** FALL THRU TO **** */
- case 0x10:
- case 0x11:
- case 0x13:
- case 0x90:
- case 0x91:
- case 0x93:
- sendbyte(ZDLE);
- c ^= 0x40;
- sendit:
- sendbyte(lastsent = c);
- break;
- default:
- if (Zctlesc && ! (c & 0x60))
- {
- sendbyte(ZDLE);
- c ^= 0x40;
- }
- sendbyte(lastsent = c);
- }
- }
- }
-
- /* Send a byte as two hex digits */
- static void zputhex(int c)
- {
- static char digits[] = "0123456789abcdef";
-
- sendbyte(digits[(c&0xF0)>>4]);
- sendbyte(digits[(c)&0xF]);
- }
-
- /*
- * Send a string to the modem
- */
- static void zmputs(char *s)
- {
- while(*s)
- sendbyte(*s++);
- }
-
- static void zsda32(char *buf, int length, int frameend)
- {
- register int c;
- register unsigned long crc;
-
- crc = 0xFFFFFFFFL;
- for (;--length >= 0; ++buf)
- {
- c = *buf & 0xFF;
- if (c & 0x60)
- sendbyte(lastsent = c);
- else
- zsendbyte(c);
- crc = update_crc32(c, crc);
- }
- sendbyte(ZDLE); sendbyte(frameend);
- crc = update_crc32(frameend, crc);
-
- crc = ~crc;
- for (length=4; --length >= 0;)
- {
- zsendbyte((int)crc);
- crc >>= 8;
- }
- }
-
- /*
- * Send binary array buf of length length, with ending ZDLE sequence frameend
- */
- static void zsdata(char *buf, int length, int frameend)
- {
- register unsigned short crc;
-
- if (Crc32t)
- zsda32(buf, length, frameend);
- else
- {
- crc = 0;
- for (;--length >= 0; ++buf)
- {
- zsendbyte(*buf); crc = update_crc16(*buf, crc);
- }
- sendbyte(ZDLE); sendbyte(frameend);
- crc = update_crc16(frameend, crc);
-
- crc = update_crc16(0, crc);
- crc = update_crc16(0, crc);
- zsendbyte(crc>>8); zsendbyte(crc);
- }
- if (frameend == ZCRCW)
- sendbyte(XON);
- }
-
- /* Send ZMODEM binary header hdr of type type */
- static void zsbh32(int type, char *hdr)
- {
- register int n;
- register unsigned long crc;
-
- sendbyte(ZBIN32); zsendbyte(type);
- crc = 0xFFFFFFFFL; crc = update_crc32(type, crc);
-
- for (n=4; --n >= 0; ++hdr)
- {
- crc = update_crc32(*hdr, crc);
- zsendbyte(*hdr);
- }
- crc = ~crc;
- for (n=4; --n >= 0;)
- {
- zsendbyte((int)crc);
- crc >>= 8;
- }
- }
-
- /* Send ZMODEM HEX header hdr of type type */
- static void zshhdr(int type, char *hdr)
- {
- register int n;
- register unsigned short crc;
-
- sendbyte(ZPAD); sendbyte(ZPAD); sendbyte(ZDLE); sendbyte(ZHEX);
- zputhex(type);
- Crc32t = 0;
-
- crc = update_crc16(type, 0);
- for (n=4; --n >= 0; ++hdr)
- {
- zputhex(*hdr); crc = update_crc16(*hdr, crc);
- }
- crc = update_crc16(0, crc);
- crc = update_crc16(0, crc);
- zputhex(crc>>8); zputhex(crc);
-
- /* Make it printable on remote machine */
- sendbyte(0xD); sendbyte(0x8A);
- /*
- * Uncork the remote in case a fake XOFF has stopped data flow
- */
- if (type != ZFIN && type != ZACK)
- sendbyte(XON);
- }
-
- /* Send ZMODEM binary header hdr of type type */
- static void zsbhdr(int type, char *hdr)
- {
- register int n;
- register unsigned short crc;
-
- sendbyte(ZPAD); sendbyte(ZDLE);
-
- if (Crc32t=Txfcs32)
- zsbh32(type, hdr);
- else
- {
- sendbyte(ZBIN); zsendbyte(type); crc = update_crc16(type, 0);
-
- for (n=4; --n >= 0; ++hdr)
- {
- zsendbyte(*hdr);
- crc = update_crc16(*hdr, crc);
- }
- crc = update_crc16(0, crc);
- crc = update_crc16(0, crc);
- zsendbyte(crc>>8);
- zsendbyte(crc);
- }
- }
-
- /* Store long integer pos in Txhdr */
- static void stohdr(long pos)
- {
- Txhdr[ZP0] = pos;
- Txhdr[ZP1] = pos>>8;
- Txhdr[ZP2] = pos>>16;
- Txhdr[ZP3] = pos>>24;
- }
-
- /*
- * Ack a ZFIN packet, let byegones be byegones
- */
- static void ackbibi(void)
- {
- register int n;
-
- stohdr(0L);
- for (n=3; --n>=0; )
- {
- purgeline();
- zshhdr(ZFIN, Txhdr);
- switch (readbyte())
- {
- case 'O':
- readbyte(); /* Discard 2nd 'O' */
- return;
- case RCDO:
- return;
- case TIMEOUT:
- default:
- break;
- }
- }
- }
-
- static void canit(void)
- {
- static char canistr[] =
- {
- 24,24,24,24,24,24,24,24,24,24,8,8,8,8,8,8,8,8,8,8,0
- };
-
- zmputs(canistr);
- }
-
-
- /*
- * Putsec writes the n characters of buf to receive file fh
- * remember to put in write err checking in here... then longjmp..
- */
- static void putsec(void)
- {
- WriteAsync(zbuffer, chinseg);
- if(zbuffer == zdiskbuff)
- {
- zbuffer += 10240L;
- }
- else
- {
- zbuffer = zdiskbuff;
- }
- chinseg = 0L;
- }
-
- /*
- * Receive a file with ZMODEM protocol
- * Assumes file name frame is in buffer
- */
- static int rzfile(void)
- {
- register int c, n;
- long rxbytes;
-
- start=0;
- if (procheader(zbuffer) == ERROR)
- return(tryzhdrtype = ZSKIP);
-
- n = 10; rxbytes = resumesize;
-
- for (;;)
- {
- chinseg = 0L;
- stohdr(rxbytes);
- zshhdr(ZRPOS, Txhdr);
- nxthdr:
- if(check_abort()) { putsec(); return ERROR; }
-
- switch (c = zgethdr(Rxhdr))
- {
- default:
- case ZNAK:
- case TIMEOUT:
- putsec();
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE) {
- return ERROR;
- }
- if ( --n < 0)
- {
- return ERROR;
- }
- case ZFILE:
- zrdata(zbuffer, 1024);
- continue;
- case ZEOF:
- putsec();
- if (rclhdr(Rxhdr) != rxbytes)
- goto nxthdr;
- /*
- * Ignore eof if it's at wrong place - force
- * a timeout because the eof might have gone
- * out before we sent our zrpos.
- */
-
- throughput(rxbytes-resumesize);
- ++Online_NFiles;
- if(!FreeDFlag)
- {
- ++DONF;
- }
- Aclose();
- return c;
- case ERROR: /* Too much garbage in header search error */
- putsec();
- if ( --n < 0)
- {
- return ERROR;
- }
- zmputs(Attn);
- continue;
- case ZSKIP:
- putsec();
- Aclose();
- return c;
- case ZDATA:
- if(!start)
- {
- throughput(0L);
- start=1;
- }
- if (rclhdr(Rxhdr) != rxbytes)
- {
- if ( --n < 0)
- return ERROR;
- putsec();
- zmputs(Attn);
- continue;
- }
- moredata:
- if(check_abort()) { putsec(); return ERROR; }
-
- if(chinseg >= ((doublebuffer) ? 8192L : 16384L))
- {
- putsec();
- }
-
- switch (c = zrdata(zbuffer+chinseg, 1024))
- {
- case ZCAN:
- putsec();
- return ERROR;
- case ERROR: /* CRC error */
- putsec();
- if ( --n < 0)
- {
- ZErrDisplay("Too many errors");
- return ERROR;
- }
- zmputs(Attn);
- continue;
- case TIMEOUT:
- putsec();
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE)
- {
- return ERROR;
- }
- if ( --n < 0)
- {
- ZErrDisplay("Too many errors");
- return ERROR;
- }
- continue;
- case GOTCRCW:
- n = 10;
- chinseg += Rxcount;
- rxbytes += Rxcount;
- stohdr(rxbytes);
- zshhdr(ZACK, Txhdr);
- sendbyte(XON);
- sprintf(sbuff, "2H%ld ",rxbytes);
- ZmodemStatPrint(sbuff);
- sprintf(sbuff, "2H%ld%% ",(ZModemInfo.Filesize?((100*rxbytes)/ZModemInfo.Filesize):0));
- ZmodemStatPrint(sbuff);
- itp(rxbytes-resumesize,1);
- ZModemInfo.RecPos=rxbytes;
- goto nxthdr;
- case GOTCRCQ:
- n = 10;
- chinseg += Rxcount;
- rxbytes += Rxcount;
- stohdr(rxbytes);
- zshhdr(ZACK, Txhdr);
- sprintf(sbuff, "2H%ld ",rxbytes);
- ZmodemStatPrint(sbuff);
- sprintf(sbuff, "2H%ld%% ",(ZModemInfo.Filesize?((100*rxbytes)/ZModemInfo.Filesize):0));
- ZmodemStatPrint(sbuff);
- itp(rxbytes-resumesize,1);
- ZModemInfo.RecPos=rxbytes;
- goto moredata;
- case GOTCRCG:
- n = 10;
- chinseg += Rxcount;
- rxbytes += Rxcount;
- sprintf(sbuff, "2H%ld ",rxbytes);
- ZmodemStatPrint(sbuff);
- sprintf(sbuff, "2H%ld%% ",(ZModemInfo.Filesize?((100*rxbytes)/ZModemInfo.Filesize):0));
- ZmodemStatPrint(sbuff);
- itp(rxbytes-resumesize,1);
- ZModemInfo.RecPos=rxbytes;
- goto moredata;
- case GOTCRCE:
- n = 10;
- chinseg += Rxcount;
- rxbytes += Rxcount;
- sprintf(sbuff, "2H%ld ",rxbytes);
- ZmodemStatPrint(sbuff);
- sprintf(sbuff, "2H%ld%% ",(ZModemInfo.Filesize?((100*rxbytes)/ZModemInfo.Filesize):0));
- ZmodemStatPrint(sbuff);
- itp(rxbytes-resumesize,1);
- ZModemInfo.RecPos=rxbytes;
- goto nxthdr;
- }
- }
- }
- }
-
- static int zmodemreceive(char *flname) /* NEED pathname!!! */
- {
- register c;
-
- RecFileNames[0]='\0';
- *(SkipdFiles+(NumSkipd*32))='\0';
- strcpy(ZPathname, flname);
-
- tryzhdrtype = ZRINIT;
- Zctlesc = FALSE;
-
- if (c=tryz()) {
- if (c == ZCOMPL) return TRUE;
- if (c == ERROR) goto fubar;
- if (c == NOCARRERROR) return FALSE;
- if (c == ZFILE) {
- if (c = rzfiles())
- goto fubar;
- return TRUE;
- }
- }
- return FALSE;
-
- fubar:
- canit();
- Aclose();
- return FALSE;
- }
-
- /*
- * Initialize for Zmodem receive attempt, try to activate Zmodem sender
- * Handles ZSINIT frame
- * Return ZFILE if Zmodem filename received, -1 on error,
- * ZCOMPL if transaction finished, else 0
- */
- static int tryz(void)
- {
- register int c, n;
-
- for (n=10; --n>=0; )
- {
- if(check_abort()) return ERROR;
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE)
- {
- return NOCARRERROR;
- }
-
- /* Set buffer length (0) and capability flags */
- stohdr(0L);
- Txhdr[ZF0] = CANFC32|CANFDX|CANOVIO|CANBRK;
- zshhdr(tryzhdrtype, Txhdr);
- if (tryzhdrtype == ZSKIP) /* Don't skip too far */
- tryzhdrtype = ZRINIT;
- again:
- switch (zgethdr(Rxhdr))
- {
- case NOCARRERROR:
- return NOCARRERROR;
- case ZRQINIT:
- continue;
- case ZEOF:
- continue;
- case TIMEOUT:
- continue;
- case ZFILE:
- tryzhdrtype = ZRINIT;
- c = zrdata(zbuffer, 1024);
- if (c == GOTCRCW)
- return ZFILE;
- zshhdr(ZNAK, Txhdr);
- goto again;
- case ZSINIT:
- Zctlesc = TESCCTL & Rxhdr[ZF0];
- if (zrdata(Attn, ZATTNLEN) == GOTCRCW)
- {
- stohdr(1L);
- zshhdr(ZACK, Txhdr);
- goto again;
- }
- zshhdr(ZNAK, Txhdr);
- goto again;
- case ZFREECNT:
- stohdr(1000000L);
- zshhdr(ZACK, Txhdr);
- goto again;
- case ZCOMMAND:
- return ERROR;
- case ZCOMPL:
- goto again;
- default:
- continue;
- case ZFIN:
- ackbibi();
- return ZCOMPL;
- case ZCAN:
- return ERROR;
- }
- }
- return 0;
- }
-
- /*
- * Receive 1 or more files with ZMODEM protocol
- */
- static int rzfiles(void)
- {
- register int c;
-
- for (;;) {
-
- if(check_abort()) return ERROR;
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE) return ERROR;
-
- switch (c = rzfile()) {
- case ZEOF:
- case ZSKIP:
- switch (tryz()) {
- case ZCOMPL: return OK;
- default: return ERROR;
- case ZFILE: break;
- }
- continue;
- default:
- return c;
- case ERROR:
- return c;
- }
- }
- }
-
- static int CheckInPlayPens(char *s)
- {
- BPTR lock1,lock2;
- UWORD loop;
-
- loop=0;
-
- do {
- if(loop==Cmds->AcLvl[LVL_NODE_NUMBER]) {
- loop++;
- }
- sprintf(GSTR1,"%snode%ld",Cmds->BBSLoc,loop);
- if(lock1=Lock(GSTR1,ACCESS_READ)) {
- sprintf(GSTR1,"%sNode%ld/PLAYPEN/%s",Cmds->BBSLoc,loop,s);
- if(lock2=Lock(GSTR1,ACCESS_READ)) {
- UnLock(lock2);
- UnLock(lock1);
- return(1);
- }
- else if(IoErr()!=205) { UnLock(lock1); return(1); }
- UnLock(lock1);
- }
- loop++;
- } while(lock1!=NULL);
- return(0);
- }
-
- /*
- * Process incoming file information header
- */
- static int procheader(char *name)
- {
- register char *p;
- int stats;
- unsigned long seconds;
- char fullname[257],string[200];
- BPTR l;
-
- strcpy(ZModemInfo.FileName,name);
- sprintf(sbuff, "2H%s",name);
- ZPrintClear("2H");
- ZmodemStatPrint(sbuff);
- ZErrDisplay("Processing Incoming Header");
-
- stats=Check_For_File(name);
- if(stats==0) stats=CheckInPlayPens(name);
- if(stats!=0) {
- ZErrDisplay("File Exists!");
- //1NOV92
- strcpy(SkipdFiles+(NumSkipd*32),name);
- NumSkipd+=1;
- *(SkipdFiles+(NumSkipd*32))='\0';
- return ERROR;
- }
- SendMasterUpload(name);
-
- strcpy(fullname, ZPathname);
- strcat(fullname, name);
- if((strlen(RecFileNames)+strlen(name)+1)<1024) {
- strcat(RecFileNames,name);
- strcat(RecFileNames," ");
- }
- else return(ERROR);
-
- filesize = 0L;
- p = name + 1 + strlen(name);
- if (*p) sscanf(p, "%ld", &filesize);
-
- l = Lock(fullname, ACCESS_READ);
- if (l) UnLock(l);
- else zresume = FALSE;
-
- if(!Aopen(fullname, (long)((zresume) ? MODE_OLDFILE : MODE_NEWFILE))) {
- ZErrDisplay("File OPEN Error!");
- return ERROR;
- }
- Seek(fh, 0L, OFFSET_END);
- resumesize = Seek(fh, 0L, OFFSET_CURRENT);
- TMPBT=filesize;
-
- if(zresume)
- sprintf(string,"\tResuming %-12s %ld bytes [%6d]\n",name,filesize,resumesize);
- else {
- sprintf(string,"\tUploading %-12s %ld bytes\n",name,filesize);
- }
- CallersLog(string);
- UDLog(string);
-
- sprintf(sbuff, "2H%ld ",filesize);
- ZModemInfo.Filesize=filesize;
- ZmodemStatPrint(sbuff);
-
- seconds = (((filesize-resumesize)/(long)(zbaud/10L))*100L)/95L;
- if(resumesize) {
- sprintf(sbuff, "2H%ld ", resumesize);
- ZmodemStatPrint(sbuff);
- ZModemInfo.ResumePos=resumesize;
- }
- else ZModemInfo.ResumePos=0L;
-
- sprintf(sbuff, "2H%ld mins %ld secs (%d) ",seconds/60L, seconds % 60L,zbaud);
- ZmodemStatPrint(sbuff);
- ZModemInfo.ApxTime=seconds;
-
- ZErrDisplay("ZDATA");
- return OK;
- }
-
- /* flname = full file name(s) */
-
- static int zmodemsend(char *flname)
- {
- int rc,y;
- char *r, *fn;
- char string[200];
- unsigned long seconds;
- struct FileInfoBlock *FBlock;
- BPTR FLock;
-
- if(getzrxinit()==ERROR) return FALSE;
-
- sendmorefiles:
- fn = &ZPathname[0];
- strcpy(ZPathname, flname);
-
- if((FLock=Lock(fn,ACCESS_READ))==NULL) return FALSE;
-
- if((FBlock=(struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL))==NULL) {
- UnLock(FLock);
- return FALSE;
- }
- if(Examine(FLock,FBlock)) {
- strcpy(ZModemInfo.FileName,FBlock->fib_FileName);
- if(FBlock->fib_Comment[0]=='F') {
- FreeDFlag=1;
- }
- else{
- FreeDFlag=0;
- }
- } else {
- UnLock(FLock);
- FreeDosObject(DOS_FIB,FBlock);
- return FALSE;
- }
- UnLock(FLock);
- FreeDosObject(DOS_FIB,FBlock);
-
- strcpy(string,Conference_Location);
- if(IsFromIcon(string,"FREEDOWNLOADS"))
- {
- FreeDFlag=1;
- }
- if(!(fh = Open(fn, MODE_OLDFILE))) return FALSE;
-
- r = fn + strlen(fn);
- while (r>=ZPathname && *r!='/' && *r!=':') r--;
-
- strlwr(++r);
- strcpy(txbuf,r);
-
- /* VERY TEMP */
- Seek(fh, 0L, OFFSET_END);
- filesize = Seek(fh, 0L, OFFSET_BEGINNING);
-
- sprintf(string, "%ld %lo %o", filesize, 0L, 0L);
- strcpy(txbuf+strlen(txbuf)+1,string);
-
- y=strlen(string);
-
- TMPBT=filesize;
- if(FreeDFlag)
- strcpy(sbuff,"Free ");
- else
- sbuff[0]='\0';
-
- sprintf(string,"\t%sDownloading %-12s %ld bytes\n",sbuff,flname,filesize);
- (void)CallersLog(string);
- (void)UDLog(string);
- (void)SendMasterDownload(ZModemInfo.FileName);
- ZPrintClear("2H");
- sprintf(sbuff, "2H%s",ZModemInfo.FileName);
- ZmodemStatPrint(sbuff);
-
- sprintf(sbuff, "2H%ld ", filesize);
- ZmodemStatPrint(sbuff);
- ZModemInfo.Filesize=filesize;
-
- seconds = (filesize/(zbaud/10L));
- sprintf(sbuff, "2H%ld mins %ld secs (%d) ",
- seconds/60L, seconds % 60L,zbaud);
- ZModemInfo.ApxTime=seconds;
- ZmodemStatPrint(sbuff);
-
- rc = zsendfile(txbuf, (int)(2+y+strlen(txbuf)));
- Close(fh);
-
- switch(rc) {
- case ERROR: canit(); return FALSE;
- case OK: case ZSKIP:
- default:
- ++Online_NFiles;
- if(!FreeDFlag)
- ++DONF;
-
- flname = flname + strlen(flname)+1;
- if(*flname) goto sendmorefiles;
- saybibi();
- return TRUE;
- }
- return(0);
- }
-
- /*
- * Get the receiver's init parameters
- */
- static int getzrxinit(void)
- {
- int n;
-
- zmputs("rz\r");
- stohdr(0L);
- zshhdr(ZRQINIT, Txhdr);
-
- for (n=10; --n>=0; ) {
- if(check_abort()) return ERROR;
-
- switch (zgethdr(Rxhdr)) {
- case ZCHALLENGE: /* Echo receiver's challenge numbr */
- stohdr(Rxpos);
- zshhdr(ZACK, Txhdr);
- continue;
- case ZCOMMAND: /* They didn't see out ZRQINIT */
- stohdr(0L);
- zshhdr(ZRQINIT, Txhdr);
- continue;
- case ZRINIT:
- Rxflags = 0xFF & Rxhdr[ZF0];
- Txfcs32 = (Rxflags & CANFC32);
- Zctlesc |= Rxflags & TESCCTL;
- Rxbuflen = (0xFF & Rxhdr[ZP0])+((0xFF & Rxhdr[ZP1])<<8);
-
- return OK;
- case ZCAN: return ERROR;
- case TIMEOUT:
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE)
- return ERROR;
-
- stohdr(0L);
- zshhdr(ZRQINIT, Txhdr);
- continue;
- case ZRQINIT:
- if (Rxhdr[ZF0] == ZCOMMAND)
- continue;
- default:
- zshhdr(ZNAK, Txhdr);
- continue;
- }
- }
- return ERROR;
- }
-
- /* Send file name and related info */
- static int zsendfile(char *buf, int blen)
- {
- register int c, n;
-
- for (n=5; --n>=0;) {
- if(check_abort()) return ERROR;
-
- Txhdr[ZF0] = 0; /* file conversion request */
- Txhdr[ZF1] = 0; /* file management request */
- Txhdr[ZF2] = 0; /* file transport request */
- Txhdr[ZF3] = 0;
- zsbhdr(ZFILE, Txhdr);
- zsdata(buf, blen, ZCRCW);
- again:
- c = zgethdr(Rxhdr);
- switch (c) {
- case ZRINIT:
- while ((c = readbyte()) > 0)
- if (c == ZPAD)
- goto again;
- case ZCAN: case ZABORT: case ZFIN:
- return ERROR;
- case ZSKIP: return c;
- case ZRPOS:
- Seek(fh, Rxpos, OFFSET_BEGINNING);
- STpos=Rxpos;
- Txpos = Rxpos;
- purgeline();
- return zsendfdata();
- case TIMEOUT:
-
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE) return ERROR;
- return ERROR;
- default:
- continue;
- }
- }
- return ERROR;
- }
-
- /* Send the data in the file */
- static int zsendfdata(void)
- {
- register int c, e, n;
- int newcnt, goodblks = 0, goodneeded = 1;
- int blklen, maxblklen;
-
- blklen = maxblklen = 1024;
- if(Rxbuflen && Rxbuflen < maxblklen)
- blklen = maxblklen = Rxbuflen;
- throughput(0L);
-
- somemore:
- if(checkline())
- {
- waitack:
- switch (c = getinsync())
- {
- default:
- case ZCAN:
- return ERROR;
- case ZSKIP:
- return c;
- case ZACK:
- break;
- case ZRPOS:
- blklen = (blklen>>1 > 64) ? blklen>>1 : 64;
- goodblks = 0;
- goodneeded = (goodneeded<<1 < 64) ? goodneeded<<1 : 64;
- break;
- case ZRINIT:
- return OK;
- }
-
- while (checkline())
- {
- switch (readbyte())
- {
- case CAN:
- case ZPAD:
- ZErrDisplay("ERROR Received");
- goto waitack;
- }
- }
- }
-
- newcnt = Rxbuflen;
- stohdr(Txpos);
- zsbhdr(ZDATA, Txhdr);
-
- do
- {
- if(check_abort()) { waitwrite(); return ERROR; }
-
- n = Read(fh, txbuf, (long)blklen);
- if (n < blklen)
- e = ZCRCE;
- else if (Rxbuflen && (newcnt -= n) <= 0)
- e = ZCRCW;
- else
- e = ZCRCG;
-
- sendbuff = zbuffer; /* tell sendbyte() to buffer the bytes in buffer */
- sendlen = 0; /* sendlen is byte buffer count */
- zsdata(txbuf, n, e);
- sendbuff = 0L;
-
- while(checkline())
- {
- switch (readbyte())
- {
- case CAN:
- case ZPAD:
- purgewrite();
- ZErrDisplay("ERROR Received");
- goto waitack;
- }
- }
-
- waitwrite();
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE)
- {
- return ERROR;
- }
- sendbuffer(zbuffer, sendlen);
- if(zbuffer == zdiskbuff)
- zbuffer += 10240L;
- else
- zbuffer = zdiskbuff;
-
- Txpos += n;
-
- sprintf(sbuff, "2H%ld ", Txpos);
- ZmodemStatPrint(sbuff);
- sprintf(sbuff, "2H%ld%% ", (ZModemInfo.Filesize?((100*Txpos)/ZModemInfo.Filesize):0));
- ZmodemStatPrint(sbuff);
- itp(Txpos-STpos,0);
- ZModemInfo.RecPos=Txpos;
-
- if(blklen < maxblklen && ++goodblks > goodneeded)
- {
- blklen = (blklen<<1 < maxblklen) ? blklen<<1 : maxblklen;
- goodblks = 0;
- goodneeded = (goodneeded>>1 > 1) ? goodneeded>>1 : 1;
- }
-
- if (e == ZCRCW)
- {
- waitwrite();
- goto waitack;
- }
-
- } while(e == ZCRCG);
-
- waitwrite();
-
- for (;;)
- {
- if(check_abort()) return ERROR;
-
- stohdr(Txpos);
- zsbhdr(ZEOF, Txhdr);
- switch(getinsync())
- {
- case ZACK:
- continue;
- case ZRPOS:
- ZErrDisplay("ERROR Received");
- goto somemore;
- case ZRINIT:
- throughput(Txpos-STpos);
- return OK;
- case ZSKIP:
- return c;
- default:
- return ERROR;
- }
- }
- }
-
- /*
- * Respond to receiver's complaint, get back in sync with receiver
- */
- static int getinsync(void)
- {
- register int c, n;
-
- for (n = 5; --n>=0;)
- {
- c = zgethdr(Rxhdr);
- purgeline();
- switch(c)
- {
- case ZCAN:
- case ZABORT:
- case ZFIN:
- return ERROR;
- case ZRPOS:
- /* ************************************* */
- /* If sending to a buffered modem, you */
- /* might send a break at this point to */
- /* dump the modem's buffer. */
- Seek(fh, Rxpos, OFFSET_BEGINNING);
- Txpos = Rxpos;
- return c;
- case ZACK:
- if (Txpos == Rxpos)
- return c;
- continue;
- case ZRINIT:
- case ZSKIP:
- return c;
- case TIMEOUT:
- zsrCDstat=CheckCarrier();
- if(zsrCDstat==FALSE) return ERROR;
- continue;
- case ERROR :
- default:
- zsbhdr(ZNAK, Txhdr);
- continue;
- }
- }
- return ERROR;
- }
-
- /* Say "bibi" to the receiver, try to do it cleanly */
- static int saybibi(void)
- {
- int n;
-
- for (n = 5; --n>=0;)
- {
- stohdr(0L); /* CAF Was zsbhdr - minor change */
- zshhdr(ZFIN, Txhdr); /* to make debugging easier */
- switch (zgethdr(Rxhdr))
- {
- case ZFIN:
- sendbyte('O'); sendbyte('O'); return OK;
- case ZCAN: return ERROR;
- case TIMEOUT:
- continue;
- }
- }
- return ERROR;
- }
- int startzmodem(char *fname,int flg)
- {
- int x;
- transfering = TRUE;
- if(flg){
- // return(zmodemsend(fname)); /* do zmodem send */
- x = zmodemsend(fname); /* do zmodem send */
-
- } else {
- // return(zmodemreceive(fname)); /* do zmodem receive */
- //(RTS) added to stop that back flow bullshit
- x = zmodemreceive(fname); /* do zmodem receive */
- // return(x);
- }
- /*if(!CheckCarrier())
- {
- DropDTR(); Delay(25L); IntDoReset(Sopt->OffHook); Delay(5L);
- }*/
- transfering=FALSE;
- return(x);
- }
-